// cf-403d
// 题意：定义整数对序列(a1, b1), (a2, b2), (a3, b3), ... , (ak, bk)为美丽，
//       当以下条件满足：
//        1. 1<=a1<=a2 < a2<=b2 < a3<=b3 < ... < ak<=bk<=n
//        2. b1-a1, b2-a2, b3-a3, ... 都是不相同的
//       问给定n和k，有多少种这样的序列，多case输入，case数2*10^5。
//
// 题解：我们可以将bi-ai看成一个数，那么假设他们的和为s，就是求n个不同的
//       数和为s，这个和spoj12943一样，不过这里第一个数可以为零，也很好
//       处理。然后数和数之间要有大于零的间隙，假设分配的和是n，那么
//       还剩下n-s填到空隙里，就是c(n-s, k)，然后k不同个数可以任意排列，
//       再乘以k!。
//       要注意到这里k不会很大，不会超过50(sqrt(n))。
//
// run: $exec < input
#include <iostream>

int const maxn = 50;
int const maxm = 1007;
long long const mo = 1000000007;
long long f[maxn][maxm];
long long c[maxm][maxm];
long long fact[maxn];
long long ans[maxm][maxm];

int main()
{
	f[0][0] = 1;
	for (int i = 1; i < maxn; i++)
		for (int j = i - 1; j < maxm; j++) {
			f[i][j] = (f[i][j] + f[i - 1][j - i + 1]) % mo;
			if (j >= i) f[i][j] = (f[i][j] + f[i][j - i]) % mo;
		}
	for (int i = 0; i < maxm; i++) {
		c[i][0] = 1;
		for (int j = 1; j <= i; j++)
			c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mo;
	}

	fact[0] = 1;
	for (int i = 1; i < maxn; i++) fact[i] = (fact[i - 1] * i) % mo;

	for (int n = 1; n < maxm; n++)
		for (int k = 1; k < maxn; k++) {
			long long tmp = 0;
			for (int s = k * (k - 1) / 2; s <= n; s++)
				tmp = (tmp + f[k][s] * c[n - s][k]) % mo;
			ans[n][k] = (tmp * fact[k]) % mo;
		}
	int T; std::cin >> T;
	for (int n, k; T-- && std::cin >> n >> k; )
		std::cout << ans[n][k] << '\n';
}

